package net.gaox.search.controller;

import com.alibaba.fastjson.JSONObject;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import net.gaox.common.annotation.IgnoreResponseAdvice;
import net.gaox.common.api.ApiResponse;
import net.gaox.search.client.SponsorClient;
import net.gaox.search.model.vo.AdPlanGetRequest;
import net.gaox.search.search.ISearch;
import net.gaox.search.search.vo.SearchRequest;
import net.gaox.search.search.vo.SearchResponse;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * <p>  </p>
 *
 * @author gaox·Eric
 * @site gaox.net
 * @date 2019/12/18 23:42
 */
@Slf4j
@RestController
public class SearchController {
    private final ISearch search;
    private final RestTemplate restTemplate;
    private final SponsorClient sponsorClient;

    public SearchController(ISearch search, RestTemplate restTemplate,
                            @Qualifier("net.gaox.search.client.SponsorClient")
                            SponsorClient sponsorClient) {
        this.search = search;
        this.restTemplate = restTemplate;
        this.sponsorClient = sponsorClient;
    }

    @PostMapping("/fetchAds")
    @HystrixCommand(fallbackMethod = "fallback")
    public ApiResponse fetchAds(@RequestBody SearchRequest request) {
        log.info("ad-search: fetchAds -> {}", JSONObject.toJSONString(request));
        SearchResponse response = search.fetchAds(request);
        Optional<Map<String, List<SearchResponse.Creative>>> optional = Optional.ofNullable(response).map(SearchResponse::getAdSlot2Ads);
        if (optional.isPresent()) {
            ApiResponse res = ApiResponse.success();
            res.putAll(optional.get());
            return res;
        }
        return ApiResponse.fail();
    }

    @IgnoreResponseAdvice
    @PostMapping("/getAdPlans")
    public ApiResponse getAdPlans(@RequestBody AdPlanGetRequest request) {
        log.info("ad-search: getAdPlans -> {}", JSONObject.toJSONString(request));
        ApiResponse body = sponsorClient.getAdPlans(request);
        log.info("get 【{}】", JSONObject.toJSONString(body));
        return body;
    }

    /**
     * 使用ribbon调用微服务接口
     *
     * @param request
     * @return
     */
    @IgnoreResponseAdvice
    @PostMapping("/getAdPlansByRibbon")
    public ApiResponse getAdPlansByRibbon(@RequestBody AdPlanGetRequest request) {
        log.info("ad-search: getAdPlansByRibbon -> {}", JSONObject.toJSONString(request));
        String url = "http://eureka-client-ad-sponsor/get/adPlan";
        ApiResponse body = restTemplate.postForEntity(url, request, ApiResponse.class).getBody();
        log.info("get 【{}】", JSONObject.toJSONString(body));
        return body;
    }

    /**
     * 获取广告 熔断器
     *
     * @param request 请求
     * @param e       异常
     * @return 熔断响应
     */
    public ApiResponse fallback(SearchRequest request, Throwable e) {
        return ApiResponse.fail("接口不能正常工作");
    }

}